package com.jingbit.ai.openai;

import android.text.TextUtils;
import android.util.Log;

import com.unfbx.chatgpt.OpenAiStreamClient;
import com.unfbx.chatgpt.entity.billing.BillingUsage;
import com.unfbx.chatgpt.entity.billing.CreditGrantsResponse;
import com.unfbx.chatgpt.entity.billing.Subscription;
import com.unfbx.chatgpt.entity.chat.ChatCompletion;
import com.unfbx.chatgpt.entity.chat.Message;
import com.unfbx.chatgpt.interceptor.OpenAILogger;
import com.unfbx.chatgpt.sse.ConsoleEventSourceListener;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;

/**
 * 描述： chatgpt
 * <p>
 * 2023-04-29
 */
public class ChatGpt {
    private static final String TAG = "jingbit:ChatGpt";
    private static String[] API_KEYS = {"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",
            "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",
            "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"};
    public volatile static int thinking = -1;
    public volatile static int tokens = 0;

    private static java.util.List<com.unfbx.chatgpt.entity.chat.Message> messages = new ArrayList<>();
    private OpenAiStreamClient client;

    public ChatGpt() {
        Message message = Message.builder().role(Message.Role.ASSISTANT).content("你的名字叫沙沙同学，是沙沙主人的最得力的智能助手！").build();
        messages.add(message);
        //国内访问需要做代理，国外服务器不需要
//        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger());
        //！！！！千万别再生产或者测试环境打开BODY级别日志！！！！
        //！！！生产或者测试环境建议设置为这三种级别：NONE,BASIC,HEADERS,！！！
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
        OkHttpClient okHttpClient = new OkHttpClient
                .Builder()
//                .proxy(proxy)
                .addInterceptor(httpLoggingInterceptor)
                .connectTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .build();
        client = OpenAiStreamClient.builder()
                .apiKey(Arrays.asList(API_KEYS))
                //自定义key的获取策略：默认KeyRandomStrategy
//                .keyStrategy(new KeyRandomStrategy())
                .keyStrategy(new FirstKeyStrategy())
                .okHttpClient(okHttpClient)
                //自己做了代理就传代理地址，没有可不不传（(关注公众号回复：openai ，获取免费的测试代理地址)）
//                .apiHost("https://自己代理的服务器地址/")
                .build();
    }

    public void subscription() {
        Subscription subscription = client.subscription();
//        Log.d("用户名：{}", subscription.getAccountName());
//        Log.d("用户总余额（美元）：{}", subscription.getHardLimitUsd());
//        Log.d("更多信息看Subscription类");
    }

    public void billingUsage() {
        LocalDate start = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            start = LocalDate.of(2023, 3, 7);
            BillingUsage billingUsage = client.billingUsage(start, LocalDate.now());
            Log.d(TAG, "总使用金额（美分）：" + billingUsage.getTotalUsage());
            Log.d(TAG, "更多信息看BillingUsage类");
        }
    }

    public void creditGrants() {
        CreditGrantsResponse creditGrantsResponse = client.creditGrants();
        Log.d("账户总余额（美元）：{}", String.valueOf(creditGrantsResponse.getTotalGranted()));
        Log.d("账户总使用金额（美元）：{}", String.valueOf(creditGrantsResponse.getTotalUsed()));
        Log.d("账户总剩余金额（美元）：{}", String.valueOf(creditGrantsResponse.getTotalAvailable()));
    }

    public void startChat(ConsoleEventSourceListener eventSourceListener, String prompt) {
        Log.d(TAG, "handleMessage startChat : " + prompt);
        if (thinking != -1 || TextUtils.isEmpty(prompt)) {
            return;
        }
        thinking = 0;
        Message message = Message.builder().role(Message.Role.USER).content(prompt).build();
        messages.add(message);
        ChatCompletion chatCompletion = ChatCompletion
                .builder()
                .model(ChatCompletion.Model.GPT_3_5_TURBO_0301.getName())
                .temperature(0.2)
                .maxTokens(3000)
                .messages(messages)
                .stream(true)
                .build();
        client.streamChatCompletion(chatCompletion, eventSourceListener);
//        CountDownLatch countDownLatch = new CountDownLatch(1);
//        try {
//            countDownLatch.await();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//            thinking=-1;
//        }
    }

//    public void startChat(String prompt) {
//        ConsoleEventSourceListener eventSourceListener = new ConsoleEventSourceListener();
//        Completion q = Completion.builder()
//                .prompt(prompt)
//                .stream(true)
//                .build();
//        client.streamCompletions(q, eventSourceListener);
//        CountDownLatch countDownLatch = new CountDownLatch(1);
//        try {
//            countDownLatch.await();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//    }
}